{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This widget tests the following\n",
    "* Sending messages from kernel to js & vice versa\n",
    "* Sending binary messages from kernel to js & vice versa"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import anywidget\n",
    "import traitlets\n",
    "\n",
    "class ByteMemoryView(traitlets.TraitType):\n",
    "    \"\"\"A trait for memory views of bytes.\"\"\"\n",
    "\n",
    "    default_value = memoryview(b'')\n",
    "    info_text = 'a memory view object'\n",
    "\n",
    "    def validate(self, obj, value):\n",
    "        if isinstance(value, memoryview) and value.format == 'B':\n",
    "            return value\n",
    "        self.error(obj, value)\n",
    "\n",
    "    def default_value_repr(self):\n",
    "        return repr(self.default_value.tobytes())\n",
    "\n",
    "\n",
    "class SampleWidget(anywidget.AnyWidget):\n",
    "    # Widget front-end JavaScript code\n",
    "    _esm = \"\"\"\n",
    "    export function render({ model, el }) {\n",
    "      let button = document.createElement(\"button\");\n",
    "      button.innerHTML = `Click Me!`;\n",
    "      button.addEventListener(\"click\", () => {\n",
    "        model.set(\"bytes\", new TextEncoder().encode(`Hello World from JavaScript`).buffer);\n",
    "        model.set(\"value\", \"Button Clicked\");\n",
    "        model.save_changes();\n",
    "      });\n",
    "      model.on(\"change:value\", () => {\n",
    "        button.innerHTML = model.get(\"value\");\n",
    "      });\n",
    "      el.appendChild(button);\n",
    "    }\n",
    "    \"\"\"\n",
    "    # Stateful property that can be accessed by JavaScript & Python\n",
    "    value = traitlets.Unicode('').tag(sync=True)\n",
    "    bytes = ByteMemoryView().tag(sync=True)\n",
    "\n",
    "widget = SampleWidget()\n",
    "widget"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(bytes(widget.bytes).decode('utf-8'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(widget.value)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "widget.value = \"Value from Python\""
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
